package model.data.wrapper;

import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import model.Utility;
import model.data.tableModel.person.Customer;
import view.GUI.mainView.KindVBox.BoxType;

/**
 * Wrapper class containing all computed values of the input and the all <code>InputWrapper</code> containing the entered counts.
 * 
 * @version %I%, %G%
 * @see InputWrapper
 *
 */
public final class ToPay {
	
	private static Logger debug = LogManager.getLogger("DEBUG");
	
	private final double depositBackValue;
	private final double drinkValue;
	private final double groceryValue;
	private final double otherValue;
	private final double depositValue;
	private final double sum;
	private final Map<BoxType, List<InputWrapper>> inputMap;
	private Customer customer;
	
	/**
	 * Creates a new wrapper.
	 * 
	 * @param depositBackValue value of the deposit that is given back
	 * @param drinkValue value of the drinks that are bought
	 * @param groceryValue value of the groceries that are bought
	 * @param otherValue value of the other goods that are bought
	 * @param depositValue value of the deposit that is bought
	 * @param inputMap Map containing all inputWrapper
	 */
	public ToPay(double depositBackValue, double drinkValue, double groceryValue, double otherValue, double depositValue, Map<BoxType, List<InputWrapper>> inputMap) {
		assert drinkValue >= 0;
		assert otherValue >= 0;
		assert groceryValue >= 0;

		this.depositBackValue = depositBackValue;
		this.depositValue = depositValue;
		this.drinkValue = drinkValue;
		this.groceryValue = groceryValue;
		this.otherValue = otherValue;
		this.sum = (depositBackValue + drinkValue + depositValue + groceryValue + otherValue);
		this.inputMap = inputMap;
		this.customer = null;
		
		debug.debug("New ToPay object created");
	}
	
	@Override
	public String toString(){
		return Utility.concatStrings("ToPay Customer: ", customer.toString(), " depositBack: ", String.valueOf(depositBackValue), " depositValue : ", String.valueOf(depositValue), " drinkValue: ", String.valueOf(drinkValue), " groceryValue: ", String.valueOf(groceryValue), " otherValue: ", String.valueOf(otherValue), " sum: ", String.valueOf(sum));
	}
	
	@Override
	public int hashCode() {

		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(depositBackValue);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(depositValue);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(drinkValue);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(groceryValue);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(otherValue);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(sum);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {

		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ToPay other = (ToPay) obj;
		if (Double.doubleToLongBits(depositBackValue) != Double.doubleToLongBits(other.depositBackValue))
			return false;
		if (Double.doubleToLongBits(depositValue) != Double.doubleToLongBits(other.depositValue))
			return false;
		if (Double.doubleToLongBits(drinkValue) != Double.doubleToLongBits(other.drinkValue))
			return false;
		if (Double.doubleToLongBits(groceryValue) != Double.doubleToLongBits(other.groceryValue))
			return false;
		if (Double.doubleToLongBits(otherValue) != Double.doubleToLongBits(other.otherValue))
			return false;
		if (Double.doubleToLongBits(sum) != Double.doubleToLongBits(other.sum))
			return false;
		return true;
	}
	
	/* GETTER AND SETTER BELOW */	

	public double getDepositValue(){
		return depositValue;
	}

	public double getDepositBackValue() {
		return depositBackValue;
	}
	
	public double getDrinkValue() {
		return drinkValue;
	}
	
	public double getGroceryValue() {
		return groceryValue;
	}
	
	public double getOtherValue() {
		return otherValue;
	}
	
	public double getSum(){
		return sum;
	}
	
	public Map<BoxType, List<InputWrapper>> getInputMap(){
		return inputMap;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
	public Customer getCustomer(){
		return customer;
	}
}
